package cn.tedu.charging.device.service.impl;

import cn.tedu.charging.common.pojo.po.ChargingGunInfoPO;
import cn.tedu.charging.common.pojo.po.ChargingStationPO;
import cn.tedu.charging.common.pojo.query.NearStationsQuery;
import cn.tedu.charging.common.pojo.vo.GunInfoVO;
import cn.tedu.charging.common.pojo.vo.StationDetailVO;
import cn.tedu.charging.common.pojo.vo.StationInfoVO;
import cn.tedu.charging.device.repository.DeviceRepository;
import cn.tedu.charging.device.service.DeviceService;
import cn.tedu.charging.device.utils.GunStatusMap;
import org.springframework.beans.BeanUtils;
import org.springframework.data.geo.GeoResult;
import org.springframework.data.redis.domain.geo.GeoLocation;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class DeviceServiceImpl implements DeviceService {
    @Resource
    private DeviceRepository deviceRepository;

    public List<StationInfoVO> nearStations(NearStationsQuery query) {
        // stationInfoVo属性 除了stationName以外 全部都来自于geo
        List<GeoResult> geoResults = deviceRepository.nearStations(query);
        if (geoResults == null) {
            return new ArrayList<>();
        }
        List<StationInfoVO> vos = geoResults.stream().map(result->{
            // 将源数据中每一个result 转化成vo
            Double distance = result.getDistance().getValue();// 从geoResult拿到了距离
            distance = new BigDecimal(distance).setScale(2, RoundingMode.HALF_UP).doubleValue();
            GeoLocation location = (GeoLocation)result.getContent();
            Double lng = location.getPoint().getX();
            Double lat = location.getPoint().getY();
            Integer stationId = (Integer)location.getName();
            // stationName 需要让仓储层查询
            String stationName = deviceRepository.getStationName(stationId);
            StationInfoVO vo = new StationInfoVO();
            vo.setStationId(stationId);
            vo.setDistance(distance);//km单位 取2位小数点 四舍五入
            vo.setStationLat(new BigDecimal(lat));
            vo.setStationLng(new BigDecimal(lng));
            vo.setStationName(stationName);
            return vo;
        }).collect(Collectors.toList());
        return vos;
    }

    public StationDetailVO detailStation(Integer stationId) {
        // 1.查询站场详情 无论从数据库返回查询结果 还是缓存都是使用po
        ChargingStationPO station = deviceRepository.getStationById(stationId);
        // 2.查询站场下所有枪列表
        List<ChargingGunInfoPO> guns = deviceRepository.getGunListByStationId(stationId);
        // 3.组织封装返回的vo
        StationDetailVO vo = new StationDetailVO();
        vo.setStationName(station.getStationName());
        vo.setAddress(station.getAddress());
        // 当前站场下的枪列表 需要用guns转化
        List<GunInfoVO> gunVOS = null;
        if (guns != null && !guns.isEmpty()){
            gunVOS = guns.stream().map(this::apply).collect(Collectors.toList());
        }
        vo.setGunInfoPOList(gunVOS);
        return vo;
    }

    private GunInfoVO apply(ChargingGunInfoPO gunPO) {
        GunInfoVO gunVO = new GunInfoVO();
        BeanUtils.copyProperties(gunPO, gunVO);
        return gunVO;
    }

    public Boolean checkGun(Integer gunId) {
        return deviceRepository.checkGun(gunId);
    }

    public void changeGunStatus(Integer id, Integer status) {
        // update charging_gun_info set gun_status = #{status} where gun_id = #{id} and gun_status in (...);
        List<Integer> statusList = GunStatusMap.get().get(status);
        deviceRepository.changeGunStatus(id, status, statusList);
    }
}
